#include "clib_cpu.h"
#include <sys/syscall.h>
#include "clib_string_util.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

static clib_cpu_info_t cpu_info[1024];
static i32_t cpu_max = -1;
static i32_t node_max = -1;

i32_t clib_get_thrd_cpu_info(clib_cpu_info_t* info)
{
    unsigned cpu, node;
    i32_t ret;
    ret = syscall (__NR_getcpu, &cpu, &node, 0);
    info->cpu = cpu;
    info->node = node;
    return ret;
}

i32_t clib_cpu_info_init() 
{
    i32_t ret;
    i32_t i;
    i32_t min;
    i32_t max;
    FILE *fh;
    u08_t cache[16*256];
    u08_t path[256];
    u08_t buffer[256];
    u08_t *sub[16];
    i32_t sub_cnt = 0;
    u08_t cache[16*256] = {0};
    u08_t *fmt = "/sys/devices/system/node%d/cpulist";
    for(i = 0; i < 16 ; i++) {
        sub[i] = &buffer[i * 256];
    }

    for(i = 0; i < 16 ; i++) {
        sprintf(path, fmt, i);
        fh = fopen(path, "rb");
        if(!fh) {
            break;
        }

        len = fgets(buffer,sizeof(buffer) , fh);

        sub_cnt = clib_string_split(sub , buffer, len, ",");

        for(i32_t j = 0; j < sub_cnt; j++) {
            ret = sscanf(sub[i],"%d-%d",&min, &max);
            if(ret == 2) {
                if(max > cpu_max) {
                    cpu_max = max + 1;
                }
                for(i32_t x = min; x <= max; x++) {
                    cpu_info[x].cpu  = x;
                    cpu_info[x].node = i; 
                }
            }
        }
    }

    node_max = i;

    return 0;
}

clib_cpu_info_t*
clib_get_cpu_info(i32_t cpu)
{
    if(cpu < cpu_max) {
        return &cpu_info[cpu];
    }
    return NULL;
}